home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
partitn.zip
/
PARTITN.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-10-20
|
19KB
|
623 lines
{$R-}
program partitn;
uses dos, crt, sounds;
const ESC = #$1b;
EndChars : set of char = ['Q','q','x','X', ESC];
type
FileNameStr = String[64];
DiskAddress = record
Head : byte;
Sector : byte;
Track : byte;
end;
PartitionRecord = record
IsStartUp : byte; { 0x80: is startup, 00: is not }
StartDA : DiskAddress;
SystemId : byte; { 1: first MS_DOS (12 bit FAT)
2: root Xenix
3: user Xenix
4: first MS_DOS (16 bit FAT)
63: Interactive Unix
F2: Second MS_DOS (either FAT)
FF: bad track info of Xenix }
EndDA : DiskAddress;
StartLogicalSector : LongInt;
NumLogicalSectors : LongInt;
end;
PartitionTable = record
BootCode : array[1..$1be] of byte;
Partitions: array[1..4] of PartitionRecord;
Marker : word;
end;
Bigbuf = array[0..511] of byte;
Var
PTfile : file of Bigbuf;
PTfilename: FileNameStr;
chh : char;
DeviceNum : byte; {info for current disk device}
DeviceChar: char;
PTtemp : PartitionTable;
PTtempx : Bigbuf Absolute PTtemp;
PT : PartitionTable;
PTx : Bigbuf absolute PT;
PTsource : FileNameStr; {where we got current PT record from}
PTdevice : char; {if from a drive, the letter}
I,J : Word;
regs : Registers;
PTDA : DiskAddress; {raw boot record disk address}
UserDA : DiskAddress; {when user enters a disk address}
PThasPartitions : Boolean; {type of recd in PT}
PThasSomething : Boolean;
SaveMainY : Byte;
Procedure DisplayHelp;
var ch:char;
begin
clrscr;
writeln('This program lets you read and write disk and partition boot records.');
writeln('It lets you move these records into a file and lets you put whatever');
writeln('you want into a boot record. You can change a partition type and can');
writeln('merge the code from one boot record with the partition table of another.');
writeln;
writeln('The program NEVER writes anything out until you enter a Write command.');
writeln('All changes are done to an in memory buffer. This buffer gets written');
writeln('by the write command. The write command asks for verification before');
writeln('overwriting a boot record on the hard disk. BUT BE CAREFUL !!!');
writeln;
writeln('For all commands, <esc>, Q, or X mean the same thing: quit to the next level');
writeln;
writeln('The first record on a disk is a boot record. It gets read in at the start');
writeln('of the boot sequence. The code in it can do whatever it wants. By');
writeln('convention a HARD disk boot record has a partition table in it. A');
writeln('partition is a hunk of disk; on the front of a BOOTABLE partition is');
writeln('another boot record. The disk boot record reads in and transfers control');
writeln('to the partition boot record. A floppy disk boot record is essentially');
writeln('a partition boot record to boot off drive A:');
writeln;
writeln('If you have a disk with two bootable systems (Unix and MS-DOS), you can');
writeln('copy the respective partition boot records to the boot record on a');
writeln('diskette. Then this diskette will directly boot that partition.');
writeln;
write('continue . . .');
beep; ch:=ReadKey; clrscr;
end {DisplayHelp};
Procedure MainWindow;
begin Window(1,1,40,25); GotoXY(1,SaveMainY); end;
Procedure PartitionWindow;
begin SaveMainY:=WhereY; Window(41,1,80,25); end;
Procedure PrintDiskAddress (Var DA:DiskAddress);
Var ccc : word;
Begin with DA do begin
ccc := ((Sector and $c0) shl 2) + Track;
write (ccc, '/', Head, '/', Sector and $3F);
end end {PrintDiskAddress};
function NullDA(DA:DiskAddress):boolean;
begin NullDA := (DA.head=0) and (DA.track=0) and (DA.sector=0); end;
Procedure PrintPartition (Var pp:PartitionRecord; num:byte);
var UnKnown:boolean;
begin with pp do begin
write(' ', num);
if IsStartup = $80 then write(' A')
else write(' ');
UnKnown:=False;
write(' type : ');
case SystemId of
1: write ('MS-DOS1 (12 fat)');
2: write ('XENIX root');
3: write ('XENIX user');
4: write ('MS-DOS1 (16 fat)');
$63: write ('Interactive Unix');
$F2: write ('MS-DOS2');
$FF: write ('XENIX bad track ');
else begin
UnKnown := True;
write ('unknown (', SystemId, ')');
end;
end {case};
writeln;
if (not NullDA(StartDA)) or (not NullDA(EndDA)) then
begin
write(' c/h/r: '); PrintDiskAddress(StartDA);
write(' to '); PrintDiskAddress(EndDA);
writeln;
end;
if (not UnKnown) or
(StartLogicalSector<>0) or (NumLogicalSectors<>0) then
writeln (' 1st/#: ', StartLogicalSector,
'/', NumLogicalSectors, ' sectors');
writeln;
end end {PrintPartition};
Function CheckRecordMarker(var PT:PartitionTable):boolean;
begin
CheckRecordMarker:=true;
if PT.Marker<>$AA55 then
begin
CheckRecordMarker:=false;
Writeln('NOT A VALID BOOT RECORD !!!'); blat;
end;
end {CheckRecordMarker};
Function CheckPartitionTable(var PT:PartitionTable):boolean;
var i,cnt:byte;
begin with PT do begin
CheckPartitionTable:=true;
cnt:=0;
for i:=1 to 4 do
if Partitions[i].IsStartUp=$80 then cnt:=cnt+1
else if Partitions[i].IsStartUp<>0 then cnt:=cnt+10;
if cnt<>1 then
begin
CheckPartitionTable:=false;
Writeln('THIS IS A VALID BOOT RECORD');
Writeln('( DOES NOT HAVE A PARTITION TABLE )');
blat;
end;
end end {CheckPartitionTable};
Procedure PrintPartitionRecord(var PT:PartitionTable);
begin with PT do begin
PartitionWindow;
clrscr;
writeln(PTsource);
PThasPartitions:=false;
if PThasSomething then
if CheckRecordMarker(PT) then
if CheckPartitionTable(PT) then
begin
PThasPartitions:=true;
for i:=4 downto 1 do
PrintPartition(PT.Partitions[i], 5-i);
end;
MainWindow;
end end {PrintPartitionRecord};
Procedure ClearDiskette(Device:byte);
{if device is diskette, read change status so IO will not fail if changed}
begin
if Device < $80 then
With Regs do begin
AH := $00;
DL := Device;
Intr($13, Regs);
writeln('** ', AH);
end;
end {ClearDiskette};
Procedure WriteDisk (Var DA:DiskAddress; Device:byte; var buffer:BigBuf);
var XX : byte;
begin with Regs, DA do begin
XX := 0;
DH := Head;
DL := Device;
CH := Track;
CL := Sector;
BX := Ofs(buffer);
ES := Seg(buffer);
Repeat
XX := XX+1;
AH := 3; {write}
AL := 1; {1 sector}
Intr($13, Regs);
Until (Device>=$80) or (XX>1) or (AH<>6);
if AH<>0 then
begin WriteLn('DISK WRITE ERROR ', AH, ' !!!'); blat; end
else
WriteLn('Record Successfully Written');
end end {WriteDisk};
Function ReadDisk (Var DA:DiskAddress; Device:byte; var buffer:BigBuf):boolean;
var XX : Byte;
begin with Regs, DA do begin
XX := 0;
DH := Head;
DL := Device;
CH := Track;
CL := Sector;
BX := Ofs(buffer);
ES := Seg(buffer);
Repeat
XX := XX+1;
AH := 2; {read}
AL := 1; {1 sector}
Intr($13, Regs);
Until (Device>=$80) or (XX>1) or (AH<>6);
ReadDisk := true;
if AH<>0 then
begin
writeln('DISK READ ERROR ', AH,